New changes which I want to add to a 1.1 version....


Summary
-------
1) Fuseballs have different scoring attributes depending upon how they
are killed.

2) due to the variable scoring, show the score above the dead fuseball for a short 
interval. 

3)Wanted to set up a way for players to be able to pass thru fuseballs that were on
the edge.

4) changed MAXSAVED value in VA.h to 1000 and MAXCRACKS value in STCrack.c to 60.

5) Wanted to make the second superzap a little smarter, ie  more likely to kill 
the most dangerous enemy on the board.

6) Added the test of Color Quickdraw to GameLoop.c in StormStart()

7) Wanted to prevent someone with System earlier than 6.0.7. from checking radio
box.

8) After the last green level, the green levels should repeat in random sequence.

9) Allow players to slip under a rotating pulsar on the edge.

10) Changed CLOT which was loaded during the level select presentation for the
invis levels.

11) Added message "Watch out for Spikes" to certain early levels.  

12) To prevent the level number and enemy counts from also being invisible
on the invis waves, I flagged for lvColor==5 and changed the VA.color = BG1
in GameLoop.c and GridTest.c

13) Added a check box to allow user to choose whether or not to show floating fuseball
scores.

14) Modified pulsar behavior to more mimick the arcade behavior.

15) Added a FlyOut routine to STFlyThru.c.

16) Changed so a zapped Tanker does not split.

17) Added a second high score list for Practice mode. 

18) Added "Save game" and "Load game" options to the Pause dialog. 

19) Added next highest score on high score list to display in upper right corner.

20) on Doomsday levels (after 96) if the player dies, a new level (random) is selected.

21) Changed the floating scores so they would not be called if a superzap was used.

22) Fixed free life flash bug.

23) Set a max of 5 lives (plus active life)

24) Added "Superzapper Recharge" message to fly-in routine.

25) Bug fix for several things related to if the starting level has been
completed.

26) changed fuseball behavior.

27) Changed extra life sound and flash related to clearing first level and 
starting bonus.

28) Another fix for GamePause.

29) Changed Levelselect to include saved game.  Added extra save game so each
play mode has game save.

30) Another attempt to fix the occassional errant zoomer box on the high scores.

--------
1) Fuseballs have different scoring attributes depending upon how they
are killed.

A fuseball hit in the lower 1/3 of the lane is worth 750, in the middle 500,
up top 250

So near the end of UpdateFuseballs()

{	if(ShotHitTest(fbp->lane,l))
					{	fbp->activeflag=0;
						NumBalls--;
						ThisLevel.fuCount--;
						ThisLevel.totalCount--;
						
						/* have different score for Fuseballs depending upon 	*/
						/* how deeply they are killed (mz) 	*/
						
						if ( (DEPTH>l) && ( l >= (int)(DEPTH*2/3) ) )
						{		/* bottom 1/3 */
							IncreaseScore(ThisLevel.fuBullseye*1.5);
							AddFLScore(x,y,ThisLevel.fuBullseye*1.5);
						}
						
						else if ( ((DEPTH*2/3)>l) && (l>=(int)(DEPTH/3)) )
						{		/* middle 1/3 */
							IncreaseScore((ThisLevel.fuBullseye));
							AddFLScore(x,y,(ThisLevel.fuBullseye));
						}
						
						else
						{		/* upper 1/3 */
							IncreaseScore(ThisLevel.fuBullseye/2);
							AddFLScore(x,y,ThisLevel.fuBullseye/2);
						}
						
						BlowFuseBall(x,y,ww.unitlen[l],fbp->rotation);
						PlayB(Blow,11);
					}
				}

				
2) due to the variable scoring, show the score above the dead fuseball for a short 
interval.  From Fuseball.c this is done with a call to AddFLScore.  Also
at the top of STFuseball.c you must include

#include "STFloatingScores.h"

the file STFloatingScores.c (included with this file) handles the floating scores.  
Appropriate lines are added to STInterface.c to alloc,init, an update the structure 
for floating scores.

Also wanted to insure that no scores were left up during FlyThru so I added
to FlyThruLoop()

	for(i=0;i<TANKTYPES;i++)
	{	ThisLevel.tk[i].count=0;
	}
	if(PlayOptions->showfscores)
		UpdateFloatingScores();				/* kill off any floating scores remaining */
	if (ThisLevel.spProb  && ThisLevel.lvNumber <=8)
		DoWatchSpikesMsg();

3)Wanted to set up a way for players to be able to pass thru fuseballs that were on
the edge.  On the real TEMPEST you could pass thru a fuseball that was on a vertex
exactly.  The closest and by easiest change I saw to make was to prevent the
fuseMask from being added to the lanestat if the fuseball was sufficiently in
the outer sublanes.  Right now I have set this as the upper and lower 4 sublanes,
allowing fully 1/16 th of the lane to be safe for a player.  To do this, modify the
test in UpdateFuseballs()

/* Test for fuseball on edge of lane (fbp->lane)*/
				/* want to add test to allow player to pass thru fuseball */
				/* as it changes lanes */
				/* So test to see if the fuseball is in the outer 16 sublanes */
				/* if it is, then let the player pass thru by not adding the fusemask */
				/* to the lanstat (mz) */
				/* eg 
				sublanes  0...3 4............................251 252....255 
				           ^^^                 ^^^^                    ^^
				           safe					dead				  safe   (mz) N*/
				           
				if(	(l<FUSEDANGERLEVEL) && 
					(fbp->sublane>(LANEDIVISIONS/16)) && 
					(fbp->sublane<(LANEDIVISIONS-LANEDIVISIONS/64)) )
				{	Hero.lanestat[fbp->lane] |= FuseMask;
				} 
		
4) changed MAXSAVED value in VA.h to 1000 and MAXCRACKS value in STCrack.c to 60.

5) Wanted to make the second superzap a little smarter, ie  more likely to kill 
the most dangerous enemy on the board.  The simplest thing I saw to do was to
change the order of the Updates() so that Fuseballs came first the, puslars, then 
flippers.  Now a fuseball is most likely to be killed.  So in STInterface.c
in STUpdate()

	UpdatePlayer();
	UpdateFuseBalls(); /* */
	UpdatePulsars();
	UpdateFlippers(); /* */
	UpdateShots();
	UpdateSpikes();
	UpdateTankers();
	UpdateCracks();
	UpdateFloatingScores();	/* mz */
	
6) Added the test of Color Quickdraw to GameLoop.c in StormStart()

#include <GestaltEqu.h>
#include <OSUtils.h>
#include <Types.h>
	
	long			myFeature;
	
	DoInits();
	
	/* Now do check for Color Quickdraw. Any version above simple 8 bit will do. */
	if(Gestalt(gestaltQuickdrawVersion, &myFeature))
		ExitToShell();
	if (myFeature < gestalt8BitQD)
	{
		Alert(201,0);
		ExitToShell();
	}

7) Wanted to prevent someone with System earlier than 6.0.7. from checking radio
box.  So I changed PlayOptions.c 

#include	<GestaltEqu.h>

void	DataToRadioButtons()
{
	int		i;
	long			myFeature;
	
	
	/* Now do check for System Version 6.0.7 for sound */
	if(Gestalt(gestaltSystemVersion, &myFeature))
		ExitToShell();
	if (myFeature < 0x0607)
	{
		PlayOptions->sys607Sound = 0;
		SetItemEnable(StartDialog,Sys607Sound,255);
	}
	.
	.
	.
	
8) After the last green level, the green levels should repeat in random sequence.
To do this I changes STResource.c.  The lvNext in LEVL 223 (level 96) points
to a non-existant LEVL 224.  Flag for that, and go into random levels.

#define RANDOMLEVELS 224		/* if it loops around */
#define STARTGREEN 208

void	STLoadLevel()
{
	register	int					i;
	register	EditorLevelType		*edp,**edh;
				int					randGreenLevel;
	static		int					highLvNum;
	
	
	/* Check to see if last green level completed (mz) */
	if (ThisLevel.lvNext == RANDOMLEVELS)
	{
		ThisLevel.lvType = 4;
		highLvNum = 97;
	}
		
	switch(ThisLevel.lvType)
	.
	.
	.
	
	case 4: 
			randGreenLevel = STARTGREEN + ((unsigned int)(Random()) % 16);
			ThisLevel= **(LevelInfo **)GetResource('LEVL',randGreenLevel);
			ThisLevel.lvType = 4;
			ThisLevel.lvNumber = highLvNum;
			highLvNum++;
			break;
			
Also had to add a lvType reset measure in GameLoop.c so the next game would
not start with the random level flag set.

long	PlayGame(HighScore,Options)
long	HighScore;
int		Options;
{
	int		i;
	
	Hero.score = -1;
	i=DoLevelSelect(&highestLastLevel);			/* transfer variable (mz) */
	ThisLevel.lvType=0;							/* reset if from random (mz) */
	if(i>=0)
	{	VA.FrameSpeed=3;
		ThisLevel.lvNext=i;
		GameLoop(Options);
	}
			
9) Allow players to slip under a rotating pulsar on the edge.  Modify STPulsar.c
UpdatePulsars()

	if(!VA.Late)				/*	Is there time to draw something?	*/
	{	if(pulsarp->mirror)		/*	Is the pulsar mirrored?			*/
			DrawPulsar(x+dx,y+dy,-dx,-dy,PulsarPower);
		else
			DrawPulsar(x,y,dx,dy,PulsarPower);
	}

	/*	Notify the player record if a pulsar is on the edge.			*/
/*	if(pulsarp->level.i==0)
	{	Hero.segmstat[pulsarp->vertex] |= PulsMask;
	} */ /* Allow player to slip under rotating pulsar */
	
10) Changed CLOT which was loaded during the level select presentation for the
invis levels.  Added a new CLOT (#5+128=133) and changed STLevelSelect.c 

int		CreateStable(stable,highestLastLevel)
.
.
.
colorresource = (*LInfo)->lvColor;
if (colorresource == 5)				/* if invis field color use grey shade 	*/
	colorresource = (*LInfo)->lvColor + 128;	/* for invisi levels (mz) 	*/
						
Causes invis levels to appear as white during level select.

Also changed CreateFit() in Gridtest.c for the same purpose

	if (ThisLevel.lvColor != 5)			/* Use alternate grey for invis levels (mz) */
		OpenStars(GetResource('CLOT',ThisLevel.lvColor));
	else
		OpenStars(GetResource('CLOT',ThisLevel.lvColor + 128));

the player will see a faint grey during "fly-in".

11) Added message "Watch out for Spikes" to certain early levels.  Did this by adding
to the file STFlythru.c.  Add the routine

void DoWatchSpikesMsg()
{
	/* This next section will add the message 				*/
	/* "Watch out for Spikes" to levels 3-8 so the new 		*/
	/* player will know to avoid them. (mz) 				*/
	
	unsigned char	*text=(void *)"\pAvoid Spikes ";
	long			targetTicks;
	
	VAMoveTo(VA.frame.right/3,VA.frame.bottom/2 - 2);
	VA.segmscale= VA.segmscale;
	if(VA.segmscale <=1) VA.segmscale=2;
	VA.color=BG1;
	VADrawText((char *)text,1,12);
	
	targetTicks = Ticks + 120;
	/* Now delay for 2 secs.  Update Player and Shots, then erase msg and return */
	while(Ticks <= targetTicks)
	{
		GameEvent();
		UpdatePlayer();
		UpdateShots();
		UpdateCracks();
		VAStep();
	}
	VAMoveTo(VA.frame.right/3,VA.frame.bottom/2 - 2);
	text=(void *)"\p             ";
	VADrawText((char *)text,1,12);
}
Then in FlyThruLoop() I added a call to it if it was the right level...

for(i=0;i<TANKTYPES;i++)
	{	ThisLevel.tk[i].count=0;
	}
	
	if (ThisLevel.spProb  && ThisLevel.lvNumber <=8 && Options == NormalPlay)
		DoWatchSpikesMsg();;
		
Note that all of the enemies are dead, so there is no way for the player to die and
leave the message on the screen.

12) To prevent the level number and enemy counts from also being invisible
on the invis waves, I flagged for lvColor==5 and changed the VA.color = BG1
in GameLoop.c and GridTest.c

in CreateFit()

	k=VA.color;
	VA.color=BG2;
	if (ThisLevel.lvColor == 5)		/* check for invis BG2 on ivis waves (mz) */
		VA.Color=BG1;
	VADrawNumber(ThisLevel.lvNumber,VA.frame.right/2-VA.segmscale-3,VA.segmscale*2+4);
	VA.color=k;
	
in GameLoop()

			if (!(PlayOptions->restart == 0))	/* only show count if Practice mode */
			{
				if (ThisLevel.lvColor == 5)		/* check for invis lvl where BG2 is */
					VA.color=BG1;				/* also invis. (mz) 				*/
				VADrawPadNumber(ThisLevel.totalCount,VA.frame.right-10,40,3);
				VADrawPadNumber(ThisLevel.edgeCount,VA.frame.right-10,60,3);
				VA.color = BG2;
			}

in STFlyThru.c
MapFlycolors()

...
FlyColors=GetResource('CLOT',ThisLevel.lvColor);
	if (ThisLevel.lcColor == 5)
		FlyColors=GetResource('CLOT',ThisLevel.lvColor + 128);
	HandToHand(&FlyColors);
	colp = (ColorSpec *)*FlyColors;
	....
	
13) Added a check box to allow user to choose whether or not to show floating fuseball
scores.

Added to PlayOptions.h

typedef	struct
{
	int		absMoveFlag;
	int		mouseSensitivity;
	int		rotationType;
	int		blankUnused;
	int		monochrome;
	int		soundOff;
	int		noLoudSounds;
	int		verticalGame;
	int		sys607Sound;
	int		restart;					/* (mz) how to restart */
	int		showfscores;
}	PlayOptionsRecord;

in DataToRadioButtons()
SetStartItem(ShowFuseScores,	PlayOptions->showfscores);

in DoStartupDialog(item)
case ShowFuseScores:	PlayOptions->showfscores= !PlayOptions->showfscores;break;			
		
in STInterface
if(PlayOptions->showfscores)
		UpdateFloatingScores();	/* mz */
		
in STFuseball.c
						if ( (DEPTH>l) && ( l >= (int)(DEPTH*2/3) ) )
						{		/* bottom 1/3 */
							IncreaseScore(ThisLevel.fuBullseye*1.5);
							if(PlayOptions->showfscores)
								AddFLScore(x,y,ThisLevel.fuBullseye*1.5);
						}
						
						else if ( ((DEPTH*2/3)>l) && (l>=(int)(DEPTH/3)) )
						{		/* middle 1/3 */
							IncreaseScore((ThisLevel.fuBullseye));
							if(PlayOptions->showfscores)
								AddFLScore(x,y,(ThisLevel.fuBullseye));
						}
						
						else
						{		/* upper 1/3 */
							IncreaseScore(ThisLevel.fuBullseye/2);
							if(PlayOptions->showfscores)
								AddFLScore(x,y,ThisLevel.fuBullseye/2);
						}
	
14) Modified pulsar behavior to more mimick the arcade behavior.  For first 25%
and last 25% of pulsar->counter, then lane Mask is not set, allowing a player
to move over it and shoot.  Change was made to DoPulsing() in STPulsar.c

	if(pulsarp->pulscounter)
	{	if(ThisLevel.puPulsDepth > pulsarp->level.i)
		{	pulsarp->pulscounter--;
			/* change in pulsar behavior so it waits then pulses, then waits */
			/* in each lane. (mz) */
			if( (pulsarp->pulscounter < (int)(PULSINGTIME*.75)) &&
					(pulsarp->pulscounter > (int)(PULSINGTIME*.25)))
				Hero.lanestat[pulsarp->lane] |= PulsMask;
			if(PulsarPower>=13 && pulsarp->pulscounter<NERVOUSNESS)
			
15) Added a FlyOut routine to STFlyThru.c.  This is called after a player
loses the last life during NormalPlay and not from a player hitting 'q' to quit.
Added the routine and added to GameLoop.c
int	FinalDeathMode=1;

						switch(Event.message & 0xFF)
						{	case 'q':
							case 'Q':
							case 27:
							case 13:	Hero.state=HeroDead;
										Hero.lives=0;				
										int	FinalDeathMode=1;
										break;
							case ' ':	/* Handled in player routine	*/
																	break;
																	
							.
							.
							.
	} while(Hero.lives>0 || Hero.state != HeroDead);
	
	if (FinalDeathMode && Options == NormalPlay)
		STFlyOutLoop();			/* test */
	
	FinalDeathMode = 1;
	
16) Changed so a zapped Tanker does not split.  In STShots.c

in ShotHitTest() I made it return a -2 is zapping

	if(Hero.superzapping)
	{	if(Hero.superzapping==2)	/*	Single enemy zap.	*/
			Hero.superzapping=0;
		return -2;					/* mz */
	}
	
Then in UpdateTanker(), change to check for a zap.  If a shot still split.

		if(zap = ShotHitTest(thetank->lane,thetank->level.i)) /* mz */
		{	PlayB(Zroom,11);
			IncreaseScore(ThisLevel.tk[thetank->tanktype].points);
			if (zap != -2)
				split=1;			/* mz */
		}
		else
			{
				ThisLevel.totalCount--;
				thetank->state=inactive;
				ActiveTankers--;
				ActiveTypes[thetank->tanktype]--;
			}
			
17) Added a second high score list for Practice mode.  Used rsrc 129 for the list, and
added appropriate other TEXT strings.  Changes wre made in HighScores.c and highmain.c.

in highscores.c...

Highscores(score)
long	score;
{
	int	i,ranking,ranky;
	Handle	ScoreHand;

	VASetColors(GetResource('CLOT',1002));
		
	
	if (PlayOptions->restart == 0)
		ScoreHand=GetResource('SCOR',128);
		

void WriteCongrats()
{
	int		x,y,i;
	int 	len;
	Handle	TextHand;
	char	*str,*Text;
	
	if (PlayOptions->restart == 0)
	{
		TextHand=GetResource('TEXT',1000);
		HLock(TextHand);
		x = VA.frame.right/3.5;
		y = VA.frame.bottom/8;
	}
	else
	{
		TextHand=GetResource('TEXT',1010);
		HLock(TextHand);
		x = VA.frame.right/4;
		y = VA.frame.bottom/8;
	}
	
	
void WriteCongrats2()
{
	int		x,y,i;
	int 	len;
	Handle	TextHand;
	char	*str,*Text;
	
	if (PlayOptions->restart == 0)
	{
		TextHand=GetResource('TEXT',132);
		HLock(TextHand);
		x = VA.frame.right/3.5;
		y = VA.frame.bottom/8;
	}
	else
	{
		TextHand=GetResource('TEXT',136);
		HLock(TextHand);
		x = VA.frame.right/4;
		y = VA.frame.bottom/8;
	}
	
in Highmain.c

HighMain() 
{
	Handle	ScoreHand;
		
	/* read scores from resources 
	ScoreHand=GetResource('SCOR',128); */
	if (PlayOptions->restart == 0)
		ScoreHand=GetResource('SCOR',128);
	else 
		ScoreHand=GetResource('SCOR',129);
	HLock(ScoreHand);
	
DisplayScores()
{
	char	Pstring[255];
	int		i,x,y,len;
	char	*str;
	Handle	TextHand;
	char	*Text;

	if (PlayOptions->restart == 0)
		TextHand=GetResource('TEXT',1001);
	else 
		TextHand=GetResource('TEXT',1011);
	
	HLock(TextHand);
	
18) Added "Save game" and "Load game" options to the Pause dialog.  

Modified GamePause.c

#include "PlayOptions.h"
extern	Player			Hero;		/* mz */

typedef struct{
		int		lvnum;
		int		lvType;
		long	score;
		int		lives;
		long	freelives;
		int		ShowFuseScores;
		int		RestartMode;
		int		Flags;
		int		NumZaps;
		} **GameRecHand, GameRec;
		
		
in GamePause(cleanup)		
		int			GameLoaded = 0;	/* mz */
		int			i;	/* mz */
		
		
					switch(ItemHit)
					{	case RotateRightRadio:
						.
						.
						.
						
						case SaveGame:
							{	GameRecHand	TheGameHand;
								GameRec		TheGame;
								
								TheGameHand = GetResource('SVGM',128);
								(**TheGameHand).lvnum = ThisLevel.lvNumber; 
								(**TheGameHand).lvType = ThisLevel.lvType;
								(**TheGameHand).lives = Hero.lives;
								(**TheGameHand).score = Hero.score;
								(**TheGameHand).freelives = Hero.freeLives;
								(**TheGameHand).ShowFuseScores = PlayOptions->showfscores;
								(**TheGameHand).RestartMode = PlayOptions ->restart;
								(**TheGameHand).Flags = Hero.Flags;
								(**TheGameHand).NumZaps = ThisLevel.plSuperZaps;
								ChangedResource(TheGameHand);
								WriteResource(TheGameHand);
								ReleaseResource(TheGameHand);
								Alert(500,0); 
							}
							break;
						case LoadGame:
							{	GameRecHand	TheGameHand;
								GameRec	TheGame;
								
								TheGameHand = GetResource('SVGM',128);
								
								PlayOptions->showfscores = (**TheGameHand).ShowFuseScores;
								PlayOptions ->restart = (**TheGameHand).RestartMode;
								
								ThisLevel.lvNext = 127 + (**TheGameHand).lvnum;
								ThisLevel.lvType = (**TheGameHand).lvType;
								STLoadLevel();
								GameLoaded = 1;		
								/* if a Doomsday level dont reset # of zaps */
								if(ThisLevel.lvType ==4)
									ThisLevel.plSuperZaps = (**TheGameHand).NumZaps;
								Hero.lives = (**TheGameHand).lives;			
								Hero.score = (**TheGameHand).score;			
								Hero.drawscore = 1;		
								Hero.freeLives = (**TheGameHand).freelives;			
								Hero.Flags = (**TheGameHand).Flags;
								ScoretoBeatIndex = 50;
								ReleaseResource(TheGameHand);
								Alert(501,0); 
							}
						 	break;
					}
				}
			}
		}
	} while(ItemHit != EndPauseButton);
	
	HideCursor();
	ShowWindow(BackdropWind);

	DisposDialog(PauseDialog);
	ShowWindow(VA.window);
	RectRgn(VA.window->visRgn,&VA.window->portRect);
	SetPort(VA.window);

	VAEraseBuffer();
	
	if(cleanup != LevelSelectRunning)
	{
		VA.segmscale=(VA.frame.bottom>>6);			/* mz */
		if(VA.segmscale<1) VA.segmscale=1;
		k=VA.color;
		VA.color=BG2;
		VADrawNumber(ThisLevel.lvNumber,VA.frame.right/2-VA.segmscale-3,VA.segmscale*2+4);
		VA.color=k;
	}

The alerts just say that a game has been saved/loaded.

19) Added next highest score on high score list to display in upper right corner.
Modified GameLoop.c, GamePause.c, and STPlayer.c.

In GameLoop.c

#include "HighScoresToBeat.h"		/* mz */

extern	Initials	*HiScoresToBeat;
extern	int 		ScoretoBeatIndex;

void	GameLoop(Options)
int		Options;
{
	int			i;
	int			startLevel=0;		/* flag for starting level (mz) */
	long int	levelStBonus=0;
	long int	levelBonus=0;
	int			levelComplete=0;
	Handle		ScoreHand;
		
	/* read scores from resources  for top right corner */
	if (PlayOptions->restart == 0)
		ScoreHand=GetResource('SCOR',128);
	else 
		ScoreHand=GetResource('SCOR',129);
	HLock(ScoreHand);
	HiScoresToBeat = (Initials *)*ScoreHand;
	ScoretoBeatIndex = 50;		/* start at the bottom */
	
	VAEraseBuffer();

	/*	Flush out some events and let MultiFinder update windows.	*/
	
int GamePause.c

extern	int				ScoretoBeatIndex;	/* mz */

case LoadGame:
							{	GameRecHand	TheGameHand;
								.
								.
								.
								ScoretoBeatIndex = 50;
							}
in STPlayer.c

#include "HighScoresToBeat.h"		/* mz */

extern	Initials	*HiScoresToBeat;
extern	int 		ScoretoBeatIndex;

void	IncreaseScore(points)
long	points;
{

	int			flashcount;
				
	.
	.
	.
	
	
	if (Hero.score > HiScoresToBeat[ScoretoBeatIndex].score)
	{
		unsigned char	*namestr=(void *)"YOU  ";
		long	scoretobeat;
		int		hsc=VA.color;
		int		x;
		
		while ((Hero.score > HiScoresToBeat[ScoretoBeatIndex].score) && ScoretoBeatIndex>=1)
			ScoretoBeatIndex--;
		if (ScoretoBeatIndex < 1) /* player now has top score */
		{	scoretobeat = Hero.score;
			ScoretoBeatIndex = 1;
		}
		else
		{	scoretobeat = HiScoresToBeat[ScoretoBeatIndex].score;
			namestr = HiScoresToBeat[ScoretoBeatIndex].name; 
		}
		VA.color = BG2; 
		if (ThisLevel.lvColor == 5)		/* check for invis lvl where BG2 is */
			VA.color=BG1;				/* also invis. (mz) 				*/
		
		VA.segmscale = Getfontscale();					/* do initials 		*/
		x = VA.frame.right - 2 - 5*(VA.segmscale + 7);
		VAMoveTo(x,20);
		VADrawText((char *) namestr,0,5);
		
		VA.segmscale=5;
		x -= 2*(VA.segmscale + 7); 						/* sub for space	*/
		VADrawPadNumber(scoretobeat,x,20,8);
		
		VA.color = hsc;
	}	/* end if */
}

20) on Doomsday levels (after 96) if the player dies, a new level (random) is selected.
If the superap has been used, it does not get recharged until a full wave is cleared.
To do this I modified STResource.c to include a lvType of 3.  This flag is set in
GameLoop.c when the player dies and the lvType == 4.  Thus instead of the normal
Redrawfield, a new level is loaded.

in STResource.c

case 3: /* case for death on doomsday levels, dont increment */
		case 4: 
			randGreenLevel = STARTGREEN + ((unsigned int)(Random()) % 16);
			ThisLevel= **(LevelInfo **)GetResource('LEVL',randGreenLevel);
			ThisLevel.lvNumber = highLvNum;
			if (ThisLevel.lvType == 4)
				highLvNum++;
			ThisLevel.lvType = 4;
			break;

in GameLoop.c

in GameLoop(Options)

	int			DoomsdayDeath = 0;


		if(Hero.state != HeroDead)
		{	AddLife();
			.
			.
			CreateFit();
		}
		else if(DoomsdayDeath)
		{
			int	numzaps=ThisLevel.plSuperZaps;
			
			ThisLevel.lvType = 3;				/* set flag for Dommsday death 		*/
			STLoadLevel(); 
			ThisLevel.plSuperZaps = numzaps;	/* Keep old # of zaps 				*/
			Hero.Flags &= (FLAGSMASK - 0x0020);	/* unset re-zap msg					*/
			CreateFit();
			Hero.Flags &= 0x0020;				/* set show re-zap msg 				*/
			DoomsdayDeath = 0;
		}
		else
		{	VA.color=0;
			RedrawField();
		}
		.
		.
		} while(Hero.state != HeroDead && Hero.state != HeroFlying);

		if(Hero.state == HeroFlying)
			STFlyThruLoop(Options);
			
		if(ThisLevel.lvType == 4 && Hero.lives>0) /* player has died in Doomsday level */
		{	DoomsdayDeath = 1;
			VA.color=-1;		/*	Black					*/
			RedrawField();
			RedrawSpikes();
		}
	
	} while(Hero.lives>0 || Hero.state != HeroDead);
	

21) Changed the floating scores so they would not be called if a superzap was used.
In STFuseball.c I changed each of the 3 calls in UpdateFuseballs() to

							if(PlayOptions->showfscores && zap != -2)
								AddFLScore(x,y,ThisLevel.fuBullseye*1.5);
and added the variable (int) zap and inserted it into the shothittest

			if(zap=ShotHitTest(fbp->lane,l))
			
A -2 is returned if a superzap is used.
From STShot.c

if(Hero.superzapping)
	{	if(Hero.superzapping==2)	/*	Single enemy zap.	*/
			Hero.superzapping=0;
		return -2;					/* mz */
	}
	
22) Whoa found a stupid bug from version 1.0.  I think adding EvenBetterBusError
allowed me to catch it.  Was using CLOT's that did not exist for the free life flash

if ((!(Hero.NewLifeColorInvert)) || (Hero.NewLifeColorInvert==12)) 
		{
			ZapColorsHandle=GetResource('CLOT',ThisLevel.lvColor);
			Hero.NewLifeColorInvert=0;
		}
		else{ /* run through all colors to enhance flash (mz) */
			ZapColorsHandle=GetResource('CLOT',(Hero.NewLifeColorInvert % 6 + 1));
			Hero.NewLifeColorInvert++;
		}
		
23) Set a max of 5 free lives (plus active life).  Added a const to STPlayer.c and
an additional if statement to IncreaseScore()

#define MAXLIVES		(5) /* (mz) */

	if (Hero.score > Hero.freeLives) 		/* check for free life (mz) 	*/
	{	
		if(Hero.lives < MAXLIVES || (Hero.lives <= MAXLIVES && Hero.state==HeroFlying))	
											/* no more than MAXLIVES lives 	*/
		{
			PlayB(ZZFreeLife,999);          /* play free life sound (mz) 	*/
			if((!PlayOptions->noLoudSounds)&&(Hero.state!=HeroFlying))
				PlayA(ZZFreeLife,999);
			Hero.NewLifeColorInvert=1;		 	/* set flash flag (mz) 		*/
			AddLife();
		}
		Hero.freeLives = Hero.score - (Hero.score % freeLifeScore) + freeLifeScore;
		/* round score up to next interval */
	}
	
24) Added "Superzapper Recharge" message to fly-in routine.  It should not happen on the
first level, and should not happen on Doomsday levels until a level has been cleared.

Mods were to Gridtest.c

extern	Player	Hero;

void DoZapRecharge(onoff)
int onoff;
{
	/* This next section will add the message 			*/
	/* "Superzapper recharge" to the screen (mz)		*/
	
	unsigned char	*text=(void *)"\pSuperzapper Recharge";
	int				x,y;
	
	if(Hero.Flags & 0x0020)
	{
		VA.segmscale = (int)(Getfontscale() * 1.5);
		if(VA.segmscale <=1) 
			VA.segmscale=2;
		x = (int)( (VA.frame.right - 20*(VA.segmscale*3 + 3))/2 );
		y = (int)(VA.frame.bottom - 2);
		VAMoveTo(x,y);
		VA.color=BG1;
		if (!onoff)					/* Erase option */
			VA.color = -1;		
		VADrawText((char *)text,1,20);
	}
}

in CreateFit()

.
.
.
	VADrawNumber(ThisLevel.lvNumber,VA.frame.right/2-VA.segmscale-3,VA.segmscale*2+4);
	VA.color=k;
		
	DoZapRecharge(1);				/* (mz) */
		
	spacehand=(void *)GetResource('SPCE',ThisLevel.lvField);
.
.
.
	for(j=0;j<ANGLES;j++)
		if(LaneSel[0][j]==-1)
			LaneSel[0][j]=space->numsegs-1;

	StarStep();

	DoZapRecharge(0);				/* (mz) */
	
	for(j=k;j<k+ANGLES/2;j++)
		LaneSel[space->numsegs][j % ANGLES]=0;

	StarStep();

25) I found a bug in my dealing with the starting level.  A saved game at startup
would deal with finishing the level saved as if it was the first level in the game,
and give the lvStBonus.  I also found it useful to have this info available with the
Superzap msg (#24), so I added a field to the Hero struct (sorry).  I updated older
things to use the new info.  To make the mode of the new variable I am using the
bit positions as flag.  As a bonus, of sorts, I could remove the NewLifeColorInvert
from the struct and use part of the Flags for that.

in Storm.h Player struct.
int		Flags; 		/* set of flags checked by bit position (mz) 	*/
						/* use by ORing and ANDing with Flags (mz)		*/
						/* 1-  Used to store CLOT # for flashing screen */
						/* 2- 	"										*/
						/* 4- 	"										*/
						/* 8-   "										*/
						/* 16- flag for if first level done (mz)		*/
						/* 32- flag for show ZapMsg	(mz)				*/
						/* 64-  unused*/
						/* 128-  etc */
}	Player;


in GameLoop.c,

- remove the startgame variable
- change things to as follows....

in GameLoop(),
update test to set flags after first wave completed
.
.
.
		if (levelComplete == 1)
			{
				/* check to see if starting level not finished (mz) 				*/
				if (!(Hero.Flags & 0x0010))
				{
					(Hero.Flags) |= 0x0030; /* set start bonus granted and show zap */
					IncreaseScore(levelStBonus); /* give starting bonus				*/
				} 
				IncreaseScore(levelBonus);
				DisplayScore();			
			}
.
.
.remove redundant tests that were here

		if(Hero.state == HeroPlaying)
			{	if(ThisLevel.edgeCount==ThisLevel.totalCount)
				{	Hero.endtimer--;
					if(Hero.endtimer<=0)
					{	Hero.state=HeroFlying;
						Hero.flydepth=0;
						levelComplete=1;
						levelStBonus=ThisLevel.lvStBonus;
						levelBonus=ThisLevel.lvBonus;
					}
				}
			}
in STPlayer.c 

-add an init statetment to ZeroScore()
	Hero.Flags = 0;	/* init new game flag */			
-update the flash flag to use the new Flags in IncreaseScore()
			Hero.Flags |= 0x0001;		 	/* set flash flag (mz) 		*/
			AddLife();
-update part where I put "flash"
	/* if lower 4 bits !=0 then colors are being flashed.  Counts up to 12	*/
	/* so it cycles thru the CLOT's twice modulo 6, then reset to 0. (mz)	*/
		
	if((Hero.superzapping==1 || Hero.Flags & 0x000F) && Hero.state != HeroFlying) 
	{	
		if ( (!(Hero.Flags & 0x000F)) || (Hero.Flags & 0x000C)==0x000C ) 
		{
			/* flashing is done	*/
			ZapColorsHandle=GetResource('CLOT',ThisLevel.lvColor);
			Hero.Flags &= 0xFFF0;
		}
		else{ /* run through all colors to enhance flash (mz) */
			ZapColorsHandle=GetResource('CLOT',((Hero.Flags & 0x000F) % 6 + 1));
			Hero.Flags++;
		}
		VASetColors(ZapColorsHandle);
		ReleaseResource(ZapColorsHandle);
	}	


			
26) Changed Fuseball behavior.  According to the Tempest gods, the fuseballs should
not stay on the edge until all other things are dead, so I changed the edge test in
STFuseballs.c

				case Brownian:
						fbp->level += fbp->levelspeed;
						if(fbp->level>(DEPTH<<4))
						{	fbp->level= (DEPTH<<4);
							if(fbp->levelspeed>0)
							{	fbp->levelspeed= - (fbp->levelspeed>>1);
							}
						}
						else
						if(fbp->level<=0)
						{	fbp->level=0;
							fbp->levelspeed=0;
							if (ThisLevel.fuCount == ThisLevel.totalCount;)
								fbp->mode=Edge; /* only have fuseballs on edge 	*/
												/*	after all else dead (mz)	*/
												
27) Changed extra life sound and flash related to clearing first level and 
starting bonus.  Should not happen on first level cleared.

			if(Hero.Flags & 0x0010)
			{
				PlayB(ZZFreeLife,999);        /* play free life sound (mz) 	*/
				if((!PlayOptions->noLoudSounds)&&(Hero.state!=HeroFlying))
					PlayA(ZZFreeLife,999);
				Hero.Flags |= 0x0001;		 /* set flash flag (mz) 		*/
			}
			AddLife();
			
28) Another fix to GamePause so level number would not be drawn during TitlesRunning.
in GamePause.c

if((cleanup != LevelSelectRunning) && (cleanup != TitlesRunning))


29) Changed Levelselect to include saved game.  Added extra save game so each
play mode has game save.

This involved basically rewriting the 
int		CreateStable(stable,highestLastLevel)
function.  The available levels for enrty into the table are stored in an array.

A flag check was also added to the end of the fcn DoLevelSelect(highestLastLevel)
with 
	if(levelnum == 0)			/* saved game was loaded as level select */
		Hero.Flags |= SavedGameStartMask;

At this same time, I moved all Hero.Flags stuff into the file heroflags.h
and replaced all hard-coded bit operands with Mask names stored in this file.

30) Another attempt to fix the occassional errant zoomer box on the high scores.

in DrawZoomer() add a second condition for MainStage == 15

		InitZoomRect(&Zoom);
		if(MainStage == 14 || MainStage == 15){	